package cn.xingzhen.jfield.ui;

import cn.xingzhen.jfield.exception.MessageException;
import cn.xingzhen.jfield.helper.StringHelper;

import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuwan [2020-03-18 01:16]
 * @since
 */
public class OracleDataField extends DataField {

    static final String ORACLE_URL = "jdbc:oracle:thin:@%s:%s:%s";

    private final String COLUMN_SQL ="SELECT TAB.COLUMN_NAME,TAB.NULLABLE, TAB.DATA_TYPE, DATA_PRECISION,"
            + "(SELECT COL.COMMENTS FROM USER_COL_COMMENTS COL "
            + "WHERE COL.TABLE_NAME='%s' "
            + "AND COL.COLUMN_NAME=TAB.COLUMN_NAME ) AS COLUMN_COMMENT, "
            + "TAB.DATA_SCALE,TAB.DATA_LENGTH FROM DBA_TAB_COLUMNS TAB "
            + "WHERE TAB.TABLE_NAME='%s' AND TAB.OWNER = '%s'";

    private Connection connection = null;
    private PreparedStatement ps = null;
    private ResultSet rs = null;
    public OracleDataField(MainFrame frame) {
        super(frame);
    }

    @Override
    public Connection getConnection() {

        String url = String.format(ORACLE_URL,
                                   getFrame().dbHost.getText(),
                                   getFrame().dbPort.getText(),
                                   getFrame().dbName.getText());
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection connection = DriverManager
                    .getConnection(url, getFrame().dbUser.getText(), getFrame().dbPassword.getText());
            return connection;
        } catch (Exception e) {
            e.printStackTrace();
            throw new MessageException("[ORACLE]创建数据库连接异常 {}", e.getMessage());
        }
    }

    @Override
    public Map<String, List<String>> getColumnTypes() {
        Map<String, List<String>> bigMap = new HashMap<>();

        // 可加 @Size 的类型
        List<String> size = new ArrayList<>();
        size.add("CHAR");
        size.add("VARCHAR");
        size.add("VARCHAR2");
        size.add("NVARCHAR");
        size.add("NVARCHAR2");
        bigMap.put(ToolConfigure.$Size, size);

        // 可加 @Max 的类型
        List<String> max = new ArrayList<>();
        max.add("INTEGER");
        bigMap.put(ToolConfigure.$Max, max);

        // 可加 @DecimalMax 的类型
        List<String> decimal = new ArrayList<>();
        decimal.add("DECIMAL");
        decimal.add("NUMERIC");
        decimal.add("NUMBER");
        decimal.add("FLOAT");
        bigMap.put(ToolConfigure.$Decimal, decimal);

        // 可加 @Date 的类型
        List<String> date = new ArrayList<>();
        date.add("DATE");
        bigMap.put(ToolConfigure.$Date, date);
        return bigMap;
    }

    @Override
    public List<FieldAttr> getColumns() throws SQLException {
        List<FieldAttr> list = new ArrayList<>();
        try {
            connection = getConnection();
            ps = connection.prepareStatement(String.format(COLUMN_SQL,
                    getFrame().tableName.getText().toUpperCase(),
                    getFrame().tableName.getText().toUpperCase(),
                    getFrame().dbName.getText().toUpperCase()));
            rs = ps.executeQuery();
            String tmp;
            while (rs.next()) {
                FieldAttr column = new FieldAttr();
                column.setName(rs.getString("COLUMN_NAME"));
                column.setComment(rs.getString("COLUMN_COMMENT"));
                tmp = rs.getString("NULLABLE");
                column.setNullable(tmp.equalsIgnoreCase("yes"));
                column.setType(rs.getString("DATA_TYPE").toLowerCase());
                tmp = rs.getString("DATA_LENGTH");
                if (StringHelper.isEmpty(tmp)) {
                    column.setMaxLength(rs.getInt("DATA_PRECISION"));
                } else {
                    column.setMaxLength(Integer.parseInt(tmp));
                }
                column.setPrecision(rs.getInt("DATA_SCALE"));
                list.add(column);
            }
            if (list.isEmpty()) throw new MessageException("未查询到任何内容，请检查表名是否错误");
        } catch (Exception e) {
            throw e;
        } finally {
            this.close();
        }
        return list;
    }

    @Override
    public void close() {
        try {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (connection != null) connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
